package com.remoter.cluster.internal;

import java.util.List;
import java.util.Random;

import com.remoter.api.cluster.support.AbstractLoadBalance;
import com.remoter.api.context.support.Exporter;
import com.remoter.api.context.support.Importer;
import com.remoter.api.extension.annotation.ExtensionName;
import com.remoter.api.util.RemoterServiceStatus;

@ExtensionName("leastactive")
public class LeastActiveLoadBalance extends AbstractLoadBalance{
	
	private final Random random = new Random();
	
	@Override
	public Exporter doSelect(Importer importer, List<Exporter> exporters) {
		int length = exporters.size(); // 总个数
        int leastActive = -1; // 最小的活跃数
        int leastCount = 0; // 相同最小活跃数的个数
        int[] leastIndexs = new int[length]; // 相同最小活跃数的下标
        int totalWeight = 0; // 总权重
        int firstWeight = 0; // 第一个权重，用于于计算是否相同
        boolean sameWeight = true; // 是否所有权重相同
        for(int i=0;i<length;i++){
        	Exporter u = exporters.get(i);
        	int active = RemoterServiceStatus.getStatus(u,importer.getMethod()).getActive();// 活跃数
        	int weight = this.getWeight(exporters.get(i));
        	if(leastActive == -1 || active < leastActive){//发现更小的活跃数，重新开始
        		leastActive = active; // 记录最小活跃数
                leastCount = 1; // 重新统计相同最小活跃数的个数
                leastIndexs[0] = i; // 重新记录最小活跃数下标
                totalWeight = weight; // 重新累计总权重
                firstWeight = weight; // 记录第一个权重
                sameWeight = true; // 还原权重相同标识
        	}else if(active == leastActive){//累计相同最小的活跃数
        		leastIndexs[leastCount ++] = i; // 累计相同最小活跃数下标
        		totalWeight += weight; //累计总权重
        		if(sameWeight && i > 0 && weight != firstWeight){
        			sameWeight = false;
        		}
        	}
        }
        if(leastCount == 1){
        	return exporters.get(leastIndexs[0]);//如果只有一个最小则直接返回
        }
        if(!sameWeight && totalWeight > 0){
        	//如果权重不相同且权重大于0则按总权重数随机
        	int offsetWeight = random.nextInt(totalWeight);
        	for(int i = 0;i<leastCount;i++){
        		int leastIndex = leastIndexs[i];
        		offsetWeight -= getWeight(exporters.get(leastIndex));
        		if(offsetWeight <= 0){
        			return exporters.get(leastIndex);
        		}
        	}
        }
        //如果权重相同或权重为0则均等随机
        return exporters.get(leastIndexs[random.nextInt(leastCount)]);
	}
	
}